/**********************************************************************

  Audacity: A Digital Audio Editor

  PlainExportOptionsEditor.cpp

  Vitaly Sverchinsky

**********************************************************************/

#include "PlainExportOptionsEditor.h"
#include <wx/config.h>

#include "BasicSettings.h"

PlainExportOptionsEditor::PlainExportOptionsEditor(std::initializer_list<OptionDesc> options,
                                                   Listener* listener)
    : mOptionsListener(listener)
{
    InitOptions(options);
}

PlainExportOptionsEditor::PlainExportOptionsEditor(std::initializer_list<OptionDesc> options,
                                                   SampleRateList sampleRates,
                                                   Listener* listener)
    : mRates(std::move(sampleRates))
    , mOptionsListener(listener)
{
    InitOptions(options);
}

std::string PlainExportOptionsEditor::GetName() const
{
    return "plain";
}

int PlainExportOptionsEditor::GetOptionsCount() const
{
    return static_cast<int>(mOptions.size());
}

bool PlainExportOptionsEditor::GetOption(int index, ExportOption& option) const
{
    if (index >= 0 && index < static_cast<int>(mOptions.size())) {
        option = mOptions[index];
        return true;
    }
    return false;
}

bool PlainExportOptionsEditor::GetValue(int id, ExportValue& value) const
{
    const auto it = mValues.find(id);
    if (it != mValues.end()) {
        value = it->second;
        return true;
    }
    return false;
}

bool PlainExportOptionsEditor::SetValue(int id, const ExportValue& value)
{
    const auto it = mValues.find(id);
    if (it != mValues.end() && it->second.index() == value.index()) {
        it->second = value;
        return true;
    }
    return false;
}

void PlainExportOptionsEditor::Load(const audacity::BasicSettings& config)
{
    auto index = 0;
    for (const auto& option : mOptions) {
        auto it = mValues.find(option.id);
        assert(it != mValues.end());
        if (auto val = std::get_if<bool>(&it->second)) {
            config.Read(mConfigKeys[index], val);
        } else if (auto val = std::get_if<int>(&it->second)) {
            config.Read(mConfigKeys[index], val);
        } else if (auto val = std::get_if<double>(&it->second)) {
            config.Read(mConfigKeys[index], val);
        } else if (auto val = std::get_if<std::string>(&it->second)) {
            wxString wxstr;
            if (config.Read(mConfigKeys[index], &wxstr)) {
                *val = wxstr.ToStdString();
            }
        }
        ++index;
    }
}

void PlainExportOptionsEditor::Store(audacity::BasicSettings& config) const
{
    auto index = 0;
    for (const auto& option : mOptions) {
        auto it = mValues.find(option.id);
        assert(it != mValues.end());
        if (auto val = std::get_if<bool>(&it->second)) {
            config.Write(mConfigKeys[index], *val);
        } else if (auto val = std::get_if<int>(&it->second)) {
            config.Write(mConfigKeys[index], *val);
        } else if (auto val = std::get_if<double>(&it->second)) {
            config.Write(mConfigKeys[index], *val);
        } else if (auto val = std::get_if<std::string>(&it->second)) {
            config.Write(mConfigKeys[index], wxString(*val));
        }

        ++index;
    }
}

ExportOptionsEditor::SampleRateList PlainExportOptionsEditor::GetSampleRateList() const
{
    return mRates;
}

void PlainExportOptionsEditor::SetSampleRateList(SampleRateList rates)
{
    mRates = std::move(rates);
    if (mOptionsListener) {
        mOptionsListener->OnSampleRateListChange();
    }
}

void PlainExportOptionsEditor::InitOptions(std::initializer_list<OptionDesc> options)
{
    assert(mOptions.empty());

    mOptions.reserve(options.size());
    mValues.reserve(options.size());
    for (auto& desc : options) {
        mValues[desc.option.id] = desc.option.defaultValue;
        mOptions.emplace_back(desc.option);
        mConfigKeys.push_back(desc.configKey);
    }
}
